home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP10.ZIP / CHAP10 / SCHMOO / IOLEOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-06-23  |  17KB  |  733 lines

  1. /*
  2.  * IOLEOBJ.CPP
  3.  * Schmoo Server Chapter 10
  4.  *
  5.  * Implementation of the IOleObject interface for Polyline.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "schmoo.h"
  18.  
  19.  
  20.  
  21. /*
  22.  * CImpIOleObject::CImpIOleObject
  23.  * CImpIOleObject::~CImpIOleObject
  24.  *
  25.  * Parameters (Constructor):
  26.  *  pObj            LPCFigure of the object we're in.
  27.  *  punkOuter       LPUNKNOWN to which we delegate.
  28.  */
  29.  
  30. CImpIOleObject::CImpIOleObject(LPCFigure pObj, LPUNKNOWN punkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_punkOuter=punkOuter;
  35.     return;
  36.     }
  37.  
  38. CImpIOleObject::~CImpIOleObject(void)
  39.     {
  40.     return;
  41.     }
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIOleObject::QueryInterface
  47.  * CImpIOleObject::AddRef
  48.  * CImpIOleObject::Release
  49.  *
  50.  * Purpose:
  51.  *  IUnknown members for CImpIOleObject object.
  52.  */
  53.  
  54. STDMETHODIMP CImpIOleObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  55.     {
  56.     return m_punkOuter->QueryInterface(riid, ppv);
  57.     }
  58.  
  59.  
  60. STDMETHODIMP_(ULONG) CImpIOleObject::AddRef(void)
  61.     {
  62.     ++m_cRef;
  63.     return m_punkOuter->AddRef();
  64.     }
  65.  
  66. STDMETHODIMP_(ULONG) CImpIOleObject::Release(void)
  67.     {
  68.     --m_cRef;
  69.     return m_punkOuter->Release();
  70.     }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /*
  77.  * CImpIOleObject::SetClientSite
  78.  *
  79.  * Purpose:
  80.  *  Provides the object with a pointer to the IOleClient site representing
  81.  *  the container in which this object resides.
  82.  *
  83.  * Parameters:
  84.  *  pIOleClientSite LPOLECLIENTSITE to the container's interface.
  85.  *
  86.  * Return Value:
  87.  *  HRESULT         NOERROR
  88.  */
  89.  
  90. STDMETHODIMP CImpIOleObject::SetClientSite(LPOLECLIENTSITE pIOleClientSite)
  91.     {
  92.     if (NULL!=m_pObj->m_pIOleClientSite)
  93.         m_pObj->m_pIOleClientSite->Release();
  94.  
  95.     m_pObj->m_pIOleClientSite=pIOleClientSite;
  96.     m_pObj->m_pIOleClientSite->AddRef();
  97.     return NOERROR;
  98.     }
  99.  
  100.  
  101.  
  102.  
  103.  
  104. /*
  105.  * CImpIOleObject::GetClientSite
  106.  *
  107.  * Purpose:
  108.  *  Asks the object for the client site provided in SetClientSite.  If
  109.  *  you have not seen SetClientSite yet, return a NULL in ppIOleClientSite.
  110.  *
  111.  * Parameters:
  112.  *  ppSite          LPOLECLIENTSITE FAR * in which to store the pointer.
  113.  *
  114.  * Return Value:
  115.  *  HRESULT         NOERROR
  116.  */
  117.  
  118. STDMETHODIMP CImpIOleObject::GetClientSite(LPOLECLIENTSITE FAR * ppSite)
  119.     {
  120.     //Be sure to AddRef the new pointer you are giving away.
  121.     *ppSite=m_pObj->m_pIOleClientSite;
  122.     m_pObj->m_pIOleClientSite->AddRef();
  123.  
  124.     return ResultFromScode(E_NOTIMPL);
  125.     }
  126.  
  127.  
  128.  
  129.  
  130.  
  131. /*
  132.  * CImpIOleObject::SetHostNames
  133.  *
  134.  * Purpose:
  135.  *  Provides the object with names of the container application and the
  136.  *  object in the container to use in object user interface.
  137.  *
  138.  * Parameters:
  139.  *  pszApp          LPCSTR of the container application.
  140.  *  pszObj          LPCSTR of some name that is useful in window titles.
  141.  *
  142.  * Return Value:
  143.  *  HRESULT         NOERROR
  144.  */
  145.  
  146. STDMETHODIMP CImpIOleObject::SetHostNames(LPCSTR pszApp, LPCSTR pszObj)
  147.     {
  148.     m_pObj->m_fEmbedded=TRUE;
  149.     m_pObj->m_pFR->UpdateEmbeddingUI(TRUE, m_pObj->m_pDoc, pszApp, pszObj);
  150.     return NOERROR;
  151.     }
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * CImpIOleObject::Close
  160.  *
  161.  * Purpose:
  162.  *  Forces the object to close down its user interface and unload.
  163.  *
  164.  * Parameters:
  165.  *  dwSaveOption    DWORD describing the circumstances under which the
  166.  *                  object is being saved and closed.
  167.  *
  168.  * Return Value:
  169.  *  HRESULT         NOERROR if successful, error code otherwise.
  170.  */
  171.  
  172. STDMETHODIMP CImpIOleObject::Close(DWORD dwSaveOption)
  173.     {
  174.     HWND        hWnd;
  175.     BOOL        fSave=FALSE;
  176.  
  177.     hWnd=m_pObj->m_pDoc->Window();
  178.  
  179.     //If object is dirty and we're asked to save, save it and close.
  180.     if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->FIsDirty())
  181.         fSave=TRUE;
  182.  
  183.     /*
  184.      * If asked to prompt, only do so if dirty, then if we get a YES,
  185.      * save as usual and close.  On NO, just close.  On CANCEL return
  186.      * OLE_E_PROMPTSAVECANCELLED.
  187.      */
  188.     if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->FIsDirty())
  189.         {
  190.         char        szTemp[80];
  191.         char        szTitle[20];
  192.         HINSTANCE   hInst;
  193.         UINT        uRet;
  194.  
  195.        #ifdef WIN32
  196.         hInst=(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
  197.        #else
  198.         hInst=(HINSTANCE)GetWindowWord(hWnd, GWW_HINSTANCE);
  199.        #endif
  200.  
  201.         LoadString(hInst, IDS_CAPTION, szTitle, sizeof(szTitle));
  202.         LoadString(hInst, IDS_MISCCLOSEPROMPT, szTemp, sizeof(szTemp));
  203.         MessageBox(hWnd, szTemp, szTitle, MB_YESNOCANCEL);
  204.  
  205.         if (IDCANCEL==uRet)
  206.             return ResultFromScode(OLE_E_PROMPTSAVECANCELLED);
  207.  
  208.         if (IDYES==uRet)
  209.             fSave=TRUE;
  210.         }
  211.  
  212.     if (fSave)
  213.         {
  214.         m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  215.         m_pObj->SendAdvise(OBJECTCODE_SAVED);
  216.         }
  217.  
  218.     //We get directly here on OLECLOSE_NOSAVE.
  219.     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  220.     return NOERROR;
  221.     }
  222.  
  223.  
  224.  
  225.  
  226.  
  227. /*
  228.  * CImpIOleObject::SetMoniker
  229.  *
  230.  * Purpose:
  231.  *  Informs the object of its moniker or its container's moniker
  232.  *  depending on dwWhich.
  233.  *
  234.  * Parameters:
  235.  *  dwWhich         DWORD describing whether the moniker is the object's
  236.  *                  or the container's.
  237.  *  pmk             LPMONIKER with the name.
  238.  *
  239.  * Return Value:
  240.  *  HRESULT         NOERROR if successful, error code otherwise.
  241.  */
  242.  
  243. STDMETHODIMP CImpIOleObject::SetMoniker(DWORD dwWhich, LPMONIKER pmk)
  244.     {
  245.     //Uninteresting for embeddings only.
  246.     return ResultFromScode(E_NOTIMPL);
  247.     }
  248.  
  249.  
  250.  
  251.  
  252.  
  253. /*
  254.  * CImpIOleObject::GetMoniker
  255.  *
  256.  * Purpose:
  257.  *  Asks the object for a moniker that can later be used to reconnect
  258.  *  to it.
  259.  *
  260.  * Parameters:
  261.  *  dwAssign        DWORD determining how to assign the moniker to
  262.  *                  to the object.
  263.  *  dwWhich         DWORD describing which moniker the caller wants.
  264.  *  ppmk            LPMONIKER FAR * into which to store the moniker.
  265.  *
  266.  * Return Value:
  267.  *  HRESULT         NOERROR if successful, error code otherwise.
  268.  */
  269.  
  270. STDMETHODIMP CImpIOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhich
  271.     , LPMONIKER FAR * ppmk)
  272.     {
  273.     //Uninteresting for embeddings only.
  274.     return ResultFromScode(E_NOTIMPL);
  275.     }
  276.  
  277.  
  278.  
  279.  
  280.  
  281. /*
  282.  * CImpIOleObject::InitFromData
  283.  *
  284.  * Purpose:
  285.  *  Initializes the object from the contents of a data object.
  286.  *
  287.  * Parameters:
  288.  *  pIDataObject    LPDATAOBJECT containing the data.
  289.  *  fCreation       BOOL indicating if this is part of a new creation.
  290.  *                  If FALSE, the container is trying to paste here.
  291.  *  dwReserved      DWORD reserved.
  292.  *
  293.  * Return Value:
  294.  *  HRESULT         NOERROR if successful, error code otherwise.
  295.  */
  296.  
  297. STDMETHODIMP CImpIOleObject::InitFromData(LPDATAOBJECT pIDataObject
  298.     , BOOL fCreation, DWORD dwReserved)
  299.     {
  300.     BOOL    fRet;
  301.  
  302.     /*
  303.      * If we get a data object here, try to paste from it.  If you've
  304.      * written clipboard code already, this is a snap.  We don't really
  305.      * care about fCreation or not since pasting in us blasts away
  306.      * whatever is already here.
  307.      */
  308.     fRet=m_pObj->m_pDoc->FPasteFromData(pIDataObject);
  309.     return fRet ? NOERROR : ResultFromScode(E_FAIL);
  310.     }
  311.  
  312.  
  313.  
  314.  
  315.  
  316. /*
  317.  * CImpIOleObject::GetClipboardData
  318.  *
  319.  * Purpose:
  320.  *  Returns an IDataObject pointer to the caller representing what would
  321.  *  be on the clipboard if the server did an Edit/Copy using OleSetClipboard.
  322.  *
  323.  * Parameters:
  324.  *  dwReserved      DWORD reserved.
  325.  *  ppIDataObj      LPDATAOBJECT FAR * into which to store the pointer.
  326.  *
  327.  * Return Value:
  328.  *  HRESULT         NOERROR if successful, error code otherwise.
  329.  */
  330.  
  331. STDMETHODIMP CImpIOleObject::GetClipboardData(DWORD dwReserved
  332.     , LPDATAOBJECT FAR * ppIDataObj)
  333.     {
  334.     /*
  335.      * Again, if you have a function to create a data object for the
  336.      * clipboard, this is a simple implementation.  The one we have
  337.      * does all the compound document formats already.
  338.      */
  339.     *ppIDataObj=m_pObj->m_pDoc->TransferObjectCreate(FALSE);
  340.     return (NULL!=*ppIDataObj) ? NOERROR : ResultFromScode(E_FAIL);
  341.     }
  342.  
  343.  
  344.  
  345.  
  346.  
  347. /*
  348.  * CImpIOleObject::DoVerb
  349.  *
  350.  * Purpose:
  351.  *  Executes an object-defined action.
  352.  *
  353.  * Parameters:
  354.  *  iVerb           LONG index of the verb to execute.
  355.  *  pMSG            LPMSG describing the event causing the activation.
  356.  *  pActiveSite     LPOLECLIENTSITE to the site involved.
  357.  *  lIndex          LONG the piece on which execution is happening.
  358.  *  hWndParent      HWND of the window in which the object can play in-place.
  359.  *  pRectPos        LPRECT of the object in hWndParent where the object
  360.  *                  can play in-place if desired.
  361.  *
  362.  * Return Value:
  363.  *  HRESULT         NOERROR if successful, error code otherwise.
  364.  */
  365.  
  366. STDMETHODIMP CImpIOleObject::DoVerb(LONG iVerb, LPMSG pMSG
  367.     , LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hWndParent
  368.     , LPCRECT pRectPos)
  369.     {
  370.     HWND            hWnd, hWndT;
  371.  
  372.     //Find the upper most window
  373.     hWndT=GetParent(m_pObj->m_pDoc->Window());
  374.  
  375.     while (NULL!=hWndT)
  376.         {
  377.         hWnd=hWndT;
  378.         hWndT=GetParent(hWndT);
  379.         }
  380.  
  381.     switch (iVerb)
  382.         {
  383.         case OLEIVERB_HIDE:
  384.             ShowWindow(hWnd, SW_HIDE);
  385.             m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  386.             break;
  387.  
  388.         case OLEIVERB_PRIMARY:
  389.         case OLEIVERB_OPEN:
  390.         case OLEIVERB_SHOW:
  391.             ShowWindow(hWnd, SW_SHOWNORMAL);
  392.             SetFocus(hWnd);
  393.  
  394.             m_pObj->SendAdvise(OBJECTCODE_SHOWOBJECT);
  395.             m_pObj->SendAdvise(OBJECTCODE_SHOWWINDOW);
  396.             break;
  397.  
  398.         default:
  399.             return ResultFromScode(OLEOBJ_S_INVALIDVERB);
  400.         }
  401.  
  402.     return NOERROR;
  403.     }
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /*
  410.  * CImpIOleObject::EnumVerbs
  411.  *
  412.  * Purpose:
  413.  *  Creates an enumerator that knows the object's verbs.  If you need
  414.  *  to change the verb list dynamically, then you'll need to implement
  415.  *  this, otherwise you can return OLE_S_USEREG.
  416.  *
  417.  * Parameters:
  418.  *  ppEnum          LPENUMOLEVERB FAR * into which to return the enum.
  419.  * Return Value:
  420.  *  HRESULT         NOERROR if successful, error code otherwise.
  421.  */
  422.  
  423. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB FAR * ppEnum)
  424.     {
  425.     //Trivial implementation if you fill the regDB.
  426.     return ResultFromScode(OLE_S_USEREG);
  427.     }
  428.  
  429.  
  430.  
  431.  
  432.  
  433. /*
  434.  * CImpIOleObject::Update
  435.  *
  436.  * Purpose:
  437.  *  Insures that the object is up to date.  This is mostly used for
  438.  *  caching but you must make sure that you recursively call all
  439.  *  nested objects you contain as well.
  440.  *
  441.  * Parameters:
  442.  *  None
  443.  *
  444.  * Return Value:
  445.  *  HRESULT         NOERROR if successful, error code otherwise.
  446.  */
  447.  
  448. STDMETHODIMP CImpIOleObject::Update(void)
  449.     {
  450.     //We're always updated since we don't contain.
  451.     return NOERROR;
  452.     }
  453.  
  454.  
  455.  
  456.  
  457.  
  458. /*
  459.  * CImpIOleObject::IsUpToDate
  460.  *
  461.  * Purpose:
  462.  *  Returns if the object is currently up to date, which involves
  463.  *  asking all contained object inside this object if they are up to
  464.  *  date as well.
  465.  *
  466.  * Parameters:
  467.  *  None
  468.  *
  469.  * Return Value:
  470.  *  HRESULT         NOERROR if successful, S_FALSE if dirty.
  471.  */
  472.  
  473. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  474.     {
  475.     //We're always updated since we don't contain.
  476.     return NOERROR;
  477.     }
  478.  
  479.  
  480.  
  481.  
  482.  
  483. /*
  484.  * CImpIOleObject::GetUserClassID
  485.  *
  486.  * Purpose:
  487.  *  Used for linked objects, this returns the class ID of what end
  488.  *  users think they are editing.
  489.  *
  490.  * Parameters:
  491.  *  pClsID          LPCLSID in which to store the CLSID.
  492.  *
  493.  * Return Value:
  494.  *  HRESULT         NOERROR if successful, error code otherwise.
  495.  */
  496.  
  497. STDMETHODIMP CImpIOleObject::GetUserClassID(LPCLSID pClsID)
  498.     {
  499.     /*
  500.      * If you are not registered to handle data other than yourself,
  501.      * then you can just return your class ID here.  If you are registered
  502.      * as usable from Treat-As dialogs, then you need to return the
  503.      * CLSID of what you are really editing.
  504.      */
  505.  
  506.     *pClsID=CLSID_Schmoo2Figure;
  507.     return NOERROR;
  508.     }
  509.  
  510.  
  511.  
  512.  
  513.  
  514. /*
  515.  * CImpIOleObject::GetUserType
  516.  *
  517.  * Purpose:
  518.  *  Determines the user-presentable name of the object.
  519.  *
  520.  * Parameters:
  521.  *  dwForm          DWORD describing which form of the string is desired.
  522.  *  pszType         LPSTR FAR * into which to return the pointer to
  523.  *                  the type string.
  524.  *
  525.  * Return Value:
  526.  *  HRESULT         NOERROR if successful, error code otherwise.
  527.  */
  528.  
  529. STDMETHODIMP CImpIOleObject::GetUserType(DWORD dwForm, LPSTR FAR * ppszType)
  530.     {
  531.     return ResultFromScode(OLE_S_USEREG);
  532.     }
  533.  
  534.  
  535.  
  536.  
  537.  
  538. /*
  539.  * CImpIOleObject::SetExtent
  540.  *
  541.  * Purpose:
  542.  *  Sets the size of the object in HIMETRIC units.
  543.  *
  544.  * Parameters:
  545.  *  dwAspect        DWORD of the aspect affected.
  546.  *  pszl            LPSIZEL containing the new size.
  547.  *
  548.  * Return Value:
  549.  *  HRESULT         NOERROR if successful, error code otherwise.
  550.  */
  551.  
  552. STDMETHODIMP CImpIOleObject::SetExtent(DWORD dwAspect, LPSIZEL pszl)
  553.     {
  554.     RECT            rc;
  555.     SIZEL           szl;
  556.  
  557.     if (!(DVASPECT_CONTENT & dwAspect))
  558.         return ResultFromScode(E_FAIL);
  559.  
  560.     XformSizeInHimetricToPixels(NULL, pszl, &szl);
  561.  
  562.     //This resizes the window to match the container's size.
  563.     SetRect(&rc, 0, 0, (int)szl.cx, (int)szl.cy);
  564.     m_pObj->m_pPL->SizeSet(&rc, TRUE);
  565.  
  566.     return NOERROR;
  567.     }
  568.  
  569.  
  570.  
  571.  
  572.  
  573. /*
  574.  * CImpIOleObject::GetExtent
  575.  *
  576.  * Purpose:
  577.  *  Retrieves the size of the object in HIMETRIC units.
  578.  *
  579.  * Parameters:
  580.  *  dwAspect        DWORD of the aspect requested
  581.  *  pszl            LPSIZEL into which to store the size.
  582.  *
  583.  * Return Value:
  584.  *  HRESULT         NOERROR if successful, error code otherwise.
  585.  */
  586.  
  587. STDMETHODIMP CImpIOleObject::GetExtent(DWORD dwAspect, LPSIZEL pszl)
  588.     {
  589.     RECT            rc;
  590.     SIZEL           szl;
  591.  
  592.     if (!(DVASPECT_CONTENT & dwAspect))
  593.         return ResultFromScode(E_FAIL);
  594.  
  595.     m_pObj->m_pPL->RectGet(&rc);
  596.     szl.cx=rc.right-rc.left;
  597.     szl.cy=rc.bottom-rc.top;
  598.  
  599.     XformSizeInPixelsToHimetric(NULL, &szl, pszl);
  600.     return NOERROR;
  601.     }
  602.  
  603.  
  604.  
  605.  
  606.  
  607. /*
  608.  * CImpIOleObject::Advise
  609.  *
  610.  * Purpose:
  611.  *  Provides an IAdviseSink to the object for notifications.
  612.  *
  613.  * Parameters:
  614.  *  pIAdviseSink    LPADVISESINK to notify.
  615.  *  pdwConn         LPDWORD into which to store a connection key.
  616.  *
  617.  * Return Value:
  618.  *  HRESULT         NOERROR if successful, error code otherwise.
  619.  */
  620.  
  621. STDMETHODIMP CImpIOleObject::Advise(LPADVISESINK pIAdviseSink, LPDWORD pdwConn)
  622.     {
  623.     if (NULL==m_pObj->m_pIOleAdviseHolder)
  624.         {
  625.         HRESULT     hr;
  626.  
  627.         hr=CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  628.  
  629.         if (FAILED(hr))
  630.             return hr;
  631.         }
  632.  
  633.     return m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink, pdwConn);
  634.     }
  635.  
  636.  
  637.  
  638.  
  639.  
  640. /*
  641.  * CImpIOleObject::Unadvise
  642.  *
  643.  * Purpose:
  644.  *  Terminates a previous advise connection from ::Advise.
  645.  *
  646.  * Parameters:
  647.  *  dwConn          DWORD connection key from ::Advise.
  648.  *
  649.  * Return Value:
  650.  *  HRESULT         NOERROR if successful, error code otherwise.
  651.  */
  652.  
  653. STDMETHODIMP CImpIOleObject::Unadvise(DWORD dwConn)
  654.     {
  655.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  656.         return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  657.  
  658.     return ResultFromScode(E_FAIL);
  659.     }
  660.  
  661.  
  662.  
  663.  
  664.  
  665. /*
  666.  * CImpIOleObject::EnumAdvise
  667.  *
  668.  * Purpose:
  669.  *  Creates and returns a enumeration of the advises on this object.
  670.  *
  671.  * Parameters:
  672.  *  ppEnum          LPENUMSTATDATA FAR * in which to return the
  673.  *                  enumerator.
  674.  *
  675.  * Return Value:
  676.  *  HRESULT         NOERROR if successful, error code otherwise.
  677.  */
  678.  
  679. STDMETHODIMP CImpIOleObject::EnumAdvise(LPENUMSTATDATA FAR * ppEnum)
  680.     {
  681.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  682.         return m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  683.  
  684.     return ResultFromScode(E_FAIL);
  685.     }
  686.  
  687.  
  688.  
  689.  
  690.  
  691. /*
  692.  * CImpIOleObject::GetMiscStatus
  693.  *
  694.  * Purpose:
  695.  *  Returns a set of miscellaneous status flags for the object.
  696.  *
  697.  * Parameters:
  698.  *  dwAspect        DWORD of the aspect in question.
  699.  *  pdwStatus       LPDWORD in which to store the flags.
  700.  *
  701.  * Return Value:
  702.  *  HRESULT         NOERROR if successful, error code otherwise.
  703.  */
  704.  
  705. STDMETHODIMP CImpIOleObject::GetMiscStatus(DWORD dwAspect, LPDWORD pdwStatus)
  706.     {
  707.     return ResultFromScode(OLE_S_USEREG);
  708.     }
  709.  
  710.  
  711.  
  712.  
  713.  
  714. /*
  715.  * CImpIOleObject::SetColorScheme
  716.  *
  717.  * Purpose:
  718.  *  Provides the object with the color palette as recommended by the
  719.  *  container application that also knows the palettes of other objects.
  720.  *  The object here is not required to use these colors.
  721.  *
  722.  * Parameters:
  723.  *  pLP             LPLOGPALETTE providing the colors.
  724.  *
  725.  * Return Value:
  726.  *  HRESULT         NOERROR if successful, error code otherwise.
  727.  */
  728.  
  729. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE pLP)
  730.     {
  731.     return ResultFromScode(E_NOTIMPL);
  732.     }
  733.